﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PSLib.CodeFormating.Lexems
{
	public class LexemList : List<Lexem>
	{
		public LexemList()
		{

		}
		public LexemList(IEnumerable<Lexem> collection)
		{
			foreach (var item in collection)
			{
				this.Add(item.Clone());
			}
		}
		public LexemList Clone()
		{
			LexemList result = new LexemList();
			foreach (var item in this)
			{
				result.Add(item.Clone());
			}
			return result;
		}

		public bool CheckSequence(int from, params object[] sequence)
		{
			if (from < 0 || from + sequence.Length >= this.Count) return false;
			int j = 0;
			bool result = true;
			for (int i = from; i < this.Count && j < sequence.Length; i++,j++)
			{
				if (sequence[j] is string)
					result = (sequence[j] as string) == this[i].LexemSource;
				else if (sequence[j] is LexemType)
					result = (LexemType)sequence[j] == this[i].Type;
				else result = false;

				if (!result) break;
			}
			return result;
		}

		public int IndexOfSequence(int from, params object[] sequence)
		{
			if (sequence == null || sequence.Length == 0) return -1;

			while (true)
			{
				int firstPos = IndexOfAny(from, sequence[0]);
				if (firstPos == -1) return -1;

				bool fullSequence = true;
				for (int i = 1; i < sequence.Length; i++)
				{
					int pos = IndexOfAny(firstPos + i, sequence[i]);
					if (pos == -1) return -1;

					if (pos == firstPos + i) continue;
					fullSequence = false;
					break;
				}
				if (fullSequence) return firstPos;
			}
		}

		public int IndexOfAny(int from, params object[] list)
		{
			int result = -1;
			bool bResult = false;
			for (int i = from; i < this.Count; i++)
			{
				for (int j = 0; j < list.Length; j++)
				{
					if (list[j] is string)
						bResult = (list[j] as string) == this[i].LexemSource;
					else if (list[j] is LexemType)
						bResult = (LexemType)list[j] == this[i].Type;
				}
				if (bResult)
				{
					result = i;
					break;
				}
			}
			return result;
		}

		public void Replace(int fromIndex, int count, object replaceObject)
		{
			if (replaceObject == null) return;
			for (int i = fromIndex; i < this.Count && i < fromIndex + count; i++)
			{
				if (replaceObject is string) this[i].LexemSource = (string)replaceObject;
				else if (replaceObject is LexemType) this[i].Type = (LexemType)replaceObject;
				else if (replaceObject is LexemCustomType) this[i].CustomType = (LexemCustomType)replaceObject;
			}
		}
	}
}
